# 处理c语言程序使其标准化
import os
import re


class Standard:
    def get_stand(self, path, txt_path): 
        str1 = self.del_notes(path, txt_path)
        str2 = self.change_position(str1, txt_path)
        str3 = self.change_typedef(str2, txt_path)
        str4 = self.do_to_while(str3, txt_path)
        str5 = self.change_struct(str4, txt_path)
        # str6 = self.change_bracket(str5, txt_path)
        str7 = self.change_define(str5, txt_path)
        str8 = self.change_array(str7, txt_path)
        str9 = self.change_hong(str8, txt_path)
        str10 = self.change_pointer(str9, txt_path)
        return str10
         
        
    # 删除行首行尾空格
    def del_blank(cls, s):
        return s.strip()   

    # 删除输入输出语句及注释及#include
    def del_notes(self, path, txt_path):
        with open(path, 'r', encoding="utf-8") as fs, open(txt_path + 'a.txt', 'w') as sw:
            first_str = fs.readline()
            while first_str:
                first_str = self.del_blank(first_str)
                str_ = ''
                #if 'printf' in first_str or 'scanf' in first_str or '#include' in first_str:
                #    first_str = ''
                if '//' in first_str or '/*' in first_str:
                    if '//' in first_str:
                        if first_str.strip().startswith('//'):
                            first_str = ''
                        else:
                            try:
                                first_str = first_str[:first_str.index('//')]
                            except:
                                pass
                    elif '/*' in first_str:
                        if '*/' in first_str:
                            try:
                                if len(first_str) > (first_str.index('*/') + 2) and first_str.index('/*') != 0:
                                    temp1 = first_str[first_str.index('/*') + 1:]
                                    temp1 = self.del_blank(temp1)
                                    temp2 = first_str[:first_str.index('/*')]
                                    temp2 = self.del_blank(temp2)
                                    first_str = temp1 + ' ' + temp2
                                elif len(first_str) > (first_str.index('*/') + 2) and first_str.index('/*') == 0:
                                    temp = first_str[first_str.index('/*') + 1:]
                                    temp = self.del_blank(temp)
                                    first_str = temp
                                else:
                                    first_str = first_str[:first_str.index('/*')]
                            except:
                                print('wrong')
                        else:
                            first_str = first_str[:first_str.index('/*')]
                            if first_str:
                                if 'printf' in first_str or 'scanf' in first_str or '#include' in first_str:
                                    first_str = ''
                                sw.write(first_str + '\n')
                            while '*/' not in first_str:
                                first_str = fs.readline()
                            first_str = ''
                if 'printf' in first_str or 'scanf' in first_str or '#include' in first_str:
                    first_str = ''
                str_ = self.del_blank(first_str)
                if str_:
                    sw.write(str_ + '\n')
                first_str = fs.readline()
        return txt_path + 'a.txt'
    
    # 将不是以{或}或；结尾的语句合并到一行
    def change_position(self, path, txt_path):
        txt_path += 'b.txt'
        with open(path, 'r') as sr, open(txt_path, 'w') as sw:
            lines = sr.readlines()
            merged_line = ''
            i = 0

            while i < len(lines):
                current_line = lines[i].strip()

                if current_line.startswith('#'):
                    sw.write(current_line + '\n')
                    i += 1
                    continue

                if not current_line.endswith('{') and \
                not current_line.endswith('}') and \
                not current_line.endswith(';'):
                    merged_line += current_line + ' '
                    i += 1
                    if i < len(lines):
                        continue
                else:
                    merged_line += current_line

                if merged_line:
                    sw.write(merged_line + '\n')
                    merged_line = ''

                i += 1
        return txt_path


    # 将typedef结构体的声明方式统一
    def change_typedef(self, path,txt_path):
        txt_path += 'c.txt'
        name = ""
        with open(path, 'r') as sr, open(txt_path, 'w') as sw:
            lines = sr.readlines()
            counter = 0
            for line in lines:
                if  line.startswith("typedef struct") :
                    sw.write("struct 替换{\n")
                    counter += 1
                elif "}"in line and counter > 0 :
                    name = line[1:-2].strip()
                    counter -= 1
                    sw.write("};\n")
                else:
                    sw.write(line)
        with open(txt_path, 'r+') as sr:
            lines = sr.readlines()
            sr.seek(0)  # 将文件指针移回文件开头
            for line in lines:
                if "替换" in line:
                    line = line.replace("替换", name)  # 将 "替换" 替换为 name
                sr.write(line)  # 将修改后的行写回        
        return txt_path
    
    
    
    # def extract_do_while(source_code):
    #     do_while_pattern = r'do\s*{[^}]*}\s*while\s*\([^)]*\);'
    #     matches = re.findall(do_while_pattern, source_code, re.DOTALL)
    #     return matches
    
    # 将do...while结构转换为while,少一次循环无视
    # def do_to_while(self, path, txt_path):
    #     txt_path += 'd.txt'
    #     with open(path, 'r') as fs, open(txt_path, 'w') as sw:
    #         lines = fs.readlines()
    #         inside_do_while = False
    #         while_conditions = []

    #         for line in lines:
    #             stripped_line = line.strip()

    #             if stripped_line.startswith("do"):
    #                 inside_do_while = True
    #                 condition = stripped_line.split("do")[1].strip()
    #                 if condition.endswith("{"):
    #                     condition = condition[:-1].strip()
    #                 while_conditions.append(condition)
    #             elif stripped_line.startswith("}") and inside_do_while:
    #                 inside_do_while = False
    #             elif inside_do_while:
    #                 sw.write(f"while ({while_conditions[-1]}) {{\n")
    #                 sw.write(line)
    #                 sw.write("}\n")
    #             else:
    #                 sw.write(line)

        # return txt_path
    def do_to_while(self, path, txt_path):
        txt_path += 'd.txt'
        with open(path, 'r') as fs, open(txt_path, 'w') as sw:
            lines = fs.readlines()
            stack = []  # 用于保存do关键字所在行号的栈

            for i, line in enumerate(lines):
                stripped_line = line.strip()

                if stripped_line.startswith("do"):
                    stack.append(i)  # 将do关键字所在行号入栈
                    sw.write(f"while () {stripped_line.split('do')[1].strip()}\n")
                elif stripped_line.startswith("}") and stack:
                    do_line_num = stack.pop()  # 弹出栈顶行号，该行号对应do关键字所在行
                    sw.write("}\n")
                elif stripped_line.startswith("while") and stack:
                    do_line_num = stack.pop()  # 弹出栈顶行号，该行号对应do关键字所在行
                    while_condition = stripped_line.split("while")[1].strip()
                    sw.write(f"}} // end of do-while\n")
                    sw.write(f"while {while_condition[1:-1]}:\n")
                else:
                    sw.write(line)  # 将其他行原样写入输出文件

        return txt_path



    # 统一struct声明方式
    def change_struct(self, path,txt_path):
        txt_path += 'e.txt'
        with open(path, 'r') as fs, open(txt_path, 'w') as sw:
            lines = fs.readlines()
            counter = 0
            temp = ""       
            for line in lines:
                if  line.startswith("struct") :
                    counter += 1
                    # print(counter)
                    if "{" in line:
                        if (line.index("{") - line.index("struct") - 6) == 0:
                            line = "typedef struct other{"
                        else:
                            temp = line[line.index("struct") + 7 : line.index("{")].strip()
                            # print(temp)
                    else:
                        if len(line) == (line.index("struct") + 6):
                            line = "typedef struct other"
                        else:
                            temp = line[line.index("struct") + 7 :].strip()
                if line.startswith("};") and counter > 0 :
                    counter -= 1
                    # print(counter)
                if "}" in line and counter > 0 :
                        temp = temp + " " + line[1:].strip()
                        sw.write("};\n")
                        sw.write(temp + '\n')
                        temp = ""
                        counter -= 1
                else:
                    sw.write(line)            
                

        return txt_path
    
    # 将大括号全部移动到行尾
    # def change_bracket(self, path, txt_path):
    #     txt_path += 'f.txt'
    #     with open(path, 'r') as sr, open(txt_path, 'w') as sw:
    #         lines = sr.readlines()
    #         if len(lines) >= 2:  # Check if there are at least two lines to process
    #             str1 = lines[0].strip()
    #             str2 = lines[1].strip()

    #             for i in range(2, len(lines) - 1):  # Loop until the second-to-last line
    #                 str_ = lines[i].strip()
    #                 if str_ and len(str_) > 0:  # Check if the string is not empty
    #                     if str_[-1] == ")" or (("if (" in str_ or "else" in str_ or "else if (" in str_ or "struct" in str_ or "switch (" in str_) and "{" not in str_):
    #                         str_ += "{"
    #                         sw.write(str_ + '\n')

    #                         if str1 == "{":
    #                             str_ = str2
    #                             str1 = lines[i + 1].strip()
    #                             str2 = lines[i + 2].strip()
    #                         elif str1 != "{":
    #                             sw.write(str1 + '\n')
    #                             sw.write("}\n")
    #                             str_ = str2
    #                             str1 = lines[i + 1].strip()
    #                             str2 = lines[i + 2].strip()
    #                     else:
    #                         sw.write(str_ + '\n')
    #                         sw.write("}\n")
    #                         str1 = str_
    #                         str2 = lines[i + 1].strip()

    #             # Handle the last iteration
    #             if len(lines) >= 2:
    #                 sw.write(str1 + '\n')
    #                 sw.write(str2 + '\n')

    #     return txt_path


    
    # 取没有空格的第一个单词
    def get_first_words(self,line):
        first_word = ""
        for temp in line:
            if temp != " " and temp != "(":
                first_word += temp
            else:
                break
        return first_word
    
    # 消除一行定义多个同种元素问题
    def change_define(self, path, txt_path):
        def replace_comma1(match):
            return match.group(0).replace(',', '、')
        def replace_comma2(match):
            return match.group(0).replace(',', '、')
        txt_path += 'g.txt'
        with open(path, 'r') as sr, open(txt_path, 'w') as sw:
            lines = sr.readlines()
            merged_line = ''
            in_statement = False  # Flag to track if currently in a multiline statement

            for line in lines:
                str1 = self.get_first_words(line)
                if (str1 in ["int", "char", "short", "long", "double", "float"]) and not ("(" in line):
                    line =  re.sub(r'\{.*?\}', replace_comma1, line)
                    variables = line.strip().split(",")
                    for variable in variables:
                       variable = re.sub(r'\{.*?\}', replace_comma2, variable)
                    for i,variable in enumerate(variables):
                        temp = variable.strip()
                        if i == 0:  # Check if it's the first variable in the line
                            # 去除类型部分
                            words = temp.split(" ")  
                            if len(words) > 1:
                                words.pop(0)  # 移除列表中的第一个单词
                                result_string = " ".join(words)  # 将剩余单词重新组合成字符串
                                temp = result_string
                                temp = temp.replace(";", "")
                            else:
                                print("字符串中没有足够的单词")
                            temp = f"{str1} {temp};"
                            
                        elif i == len(variables) - 1:  # Check if it's the last variable in the line
                            temp = f"{str1} {temp}"  # Add a semicolon for the last variable
                        else:
                            temp = f"{str1} {temp};"
                        sw.write(temp + '\n')
                else:
                    sw.write(line)

        return txt_path
    
    # 统一数组的定义形式
    def change_array(self, path,txt_path):
        txt_path += 'h.txt'
        with open(path, 'r') as sr, open(txt_path, 'w') as sw:
            lines = sr.readlines()
            for line in lines:
                str1 = self.get_first_words(line)
                if "[" in line:
                    if str1 in ("int", "char", "short", "long", "double", "float"):
                        if "=" in line:
                            if line.index("[") < line.index("="):
                                str2 = line[:line.index("=")] + ";"
                                sw.write(str2 + '\n')
                            else:
                                sw.write(line)
                        else:
                            sw.write(line)
                    else:
                        sw.write(line)
                else:
                    sw.write(line)

        return txt_path
    
    # 直接替换宏定义
    def change_hong(self, path, txt_path):
        txt_path += 'i.txt'
        hong_key = None  # 初始化 hong_key 变量

        with open(path, 'r') as sr, open(txt_path, 'w') as sw:
            lines = sr.readlines()
            for line in lines:
                if "#define" in line:
                    temp = line.replace(" ", "")
                    if len(line) - len(temp) == 2:
                        hong_key = self.get_hong_key(line)
                        hong_value = self.get_hong_value(line)
                        if hong_key and hong_value:
                            continue
                if hong_key and hong_key in line:  # 在检查 hong_key 是否存在之前，需要确保它被分配了值
                    line = line.replace(hong_key, hong_value)
                sw.write(line)

        return txt_path

    
    # 获取宏定义的标识符
    def get_hong_key(self,str):
        index = str.index(" ") + 1
        str1 = str[index:]
        key = str1[:str1.index(" ")]
        return key
    
    # 获取宏定义的替换值
    def get_hong_value(self,str):
        index = str.index(" ") + 1
        str1 = str[index:]
        value = str1[str1.index(" ") + 1:-1]
        return value
    
    # 指针格式的变化
    def change_pointer(self, path, txt_path):
        txt_path += "j.txt"
        with open(path, 'r') as sr, open(txt_path, 'w') as sw:
            lines = sr.readlines()
            for line in lines:
                if "*" in line and " *" not in line:
                    line = line.replace("*", " *")
                if "*" in line and "* " not in line:
                    line = line.replace("*", "* ")
                sw.write(line)
        return txt_path
    
    
    
